#pragma once

#include <fstream>
#include <iostream>


enum LogLevel
{
	LogFatal = 0,
	LogError,
    LogWarn,
	LogInfo,
	LogDebug,
	LogTrace,
};
static const char * typeStrFromLogLevel[] = {"FATAL|", "ERROR|", "WARN|", "INFO|", "DEBUG|", "TRACE|"};

class Logger
{
public:
	Logger(const char * filename = NULL);
	~Logger();
	void reopen(struct tm&);
	Logger& prolog(LogLevel ll);
    template <typename T>
	void write(LogLevel ll, const T& value);
	template <typename T>
	inline Logger& operator<<(const T& val)
	{
		*_ostr << val;
		return *this;
	}

private:
	std::string _filename;
	int _lastDay;
	std::ostream * _ostr;
};

template <typename T>
void Logger::write(LogLevel ll, const T &value)
{
    time_t t = time(NULL);
    tm aTm;
    localtime_r(&t, &aTm);
    if(aTm.tm_mday != _lastDay)
    {
        reopen(aTm);
        _lastDay = aTm.tm_mday;
    }
    char fmtStr[512] = {0};
    snprintf(fmtStr, sizeof(fmtStr), "%02d:%02d:%02d|", aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
    *_ostr << typeStrFromLogLevel[ll] << fmtStr << value;
    *_ostr << std::endl;
}